package models;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Page;
import play.db.ebean.Model;
import play.data.validation.Constraints;

/**
 * Modele du Chapitre. Un chapitre est reliée à une Matiere.
 * 
 * @author ProjetSI-QCM
 * 
 */
/**
 * @author maletell
 *
 */
@SuppressWarnings("serial")
@Entity
public class Chapitre extends Model {

	/**
	 * l'identifiant du Chapitre.
	 */
	@Id
	private Long idChapitre;

	/**
	 * Référence vers la Matiere du chapitre.
	 */
	@ManyToOne
	private Matiere matiere;
	/**
	 * Liste des questions du Chapitre.
	 */
	private List<Question> sesQuestions = new ArrayList<Question>();

	/**
	 * Libelle du Chapitre.
	 */
	@Constraints.Required
	private String libelleC;

	/**
	 * Finder de la classe Chapitre.
	 */
	private static Finder<Long, Chapitre> find = new Finder<Long, Chapitre>(
			Long.class, Chapitre.class);

	/**
	 * Permet de recupérer un Chapitre à partir de son Id.
	 * 
	 * @param id
	 *            l'id du Chapitre a récupérer
	 * @return Chapitre l'objet Chapitre
	 */
	public static Chapitre findById(final Long id) {
		return Ebean.find(Chapitre.class, id);
	}

	/**
	 * Permet de récupérer la liste des Chapitres correspondants à une Matiere.
	 * 
	 * @param mat
	 *            La Matiere
	 * @return List<Chapitre> La liste des chapitres correspondants à la Matiere
	 */
	public static List<Chapitre> findByMatiere(final Matiere mat) {
		return find.where().eq("matiere", mat).findList();
	}

	/**
	 * Permet de récupérer tous les Chapitres.
	 * 
	 * @return List<Chapitre>
	 */
	public static List<Chapitre> findAll() {
		return find.all();
	}

	/**
	 * Sauvegarde un Chapitre dans la Base de Données.
	 * 
	 * @param chapitre
	 *            Objet a créer.
	 */
	public static void create(final Chapitre chapitre) {
		chapitre.save();
	}

	/**
	 * Met à jour un Chapitre dans la Base de Données.
	 * 
	 * @param chapitre
	 *            Objet a Modifier
	 */
	public static void update(final Chapitre chapitre) {
		chapitre.update();
	}

    /**
     * Permet de Supprimer un Chapitre de la base de données.
     * 
     * @param id
     *            L'identifiant du Chapitre à supprimer.
     */
	public static void delete(final Long id) {
		Chapitre chapitre = Chapitre.findById(id);
		for (Question question : chapitre.getSesQuestions()) {
			Question.delete(question.getIdQuestion());
		}
		find.ref(id).delete();
	}

	/**
	 * Liste des options pour les listes déroulantes.
	 * 
	 * @return Map<String,String>
	 */
	public static Map<String, String> options() {
		final LinkedHashMap<String, String> options = 
				new LinkedHashMap<String, String>();
		for (Chapitre c : Chapitre.find.orderBy("libelleC").findList()) {
			options.put(c.getIdChapitre().toString(), c.getLibelleC());
		}
		return options;
	}

	/**
	 * Retourne une Page de Chapitre.
	 * 
	 * @param page
	 *            Page à afficher
	 * @param pageSize
	 *            Nombre d'objets par page
	 * @param sortBy
	 *            Propriété utilisée pour le tri
	 * @param order
	 *            Sens du tri (asc ou desc)
	 * @param filter
	 *            Filtre appliqué sur le nom de la colonne
	 * @return Page<Chapitre> la page
	 */
	public static Page<Chapitre> page(final int page, final int pageSize,
			final String sortBy, final String order, final String filter) {
		return find.where().ilike("libelleC", "%" + filter + "%")
				.orderBy(sortBy + " " + order).fetch("matiere")
				.findPagingList(pageSize).setFetchAhead(false).getPage(page);
	}

	/**
	 * @return the idChapitre
	 */
	public final Long getIdChapitre() {
		return idChapitre;
	}

	/**
	 * @param id the idChapitre to set
	 */
	public final void setIdChapitre(final Long id) {
		this.idChapitre = id;
	}

	/**
	 * @return the matiere
	 */
	public final Matiere getMatiere() {
		return matiere;
	}

	/**
	 * @param m the matiere to set
	 */
	public final void setMatiere(final Matiere m) {
		this.matiere = m;
	}

	/**
	 * @return the sesQuestions
	 */
	@OneToMany(mappedBy = "chapitre", cascade = CascadeType.ALL)
	public final List<Question> getSesQuestions() {
		return sesQuestions;
	}

	/**
	 * @param l the sesQuestions to set
	 */
	public final void setSesQuestions(final List<Question> l) {
		this.sesQuestions = l;
	}

	/**
	 * @return the libelleC
	 */
	public final String getLibelleC() {
		return libelleC;
	}

	/**
	 * @param l the libelleC to set
	 */
	public final void setLibelleC(final String l) {
		this.libelleC = l;
	}

}
